package com.example.fileuploaddownload.service.impl;

import com.example.fileuploaddownload.entity.FileChunk;
import com.example.fileuploaddownload.mapper.FileChunkMapper;
import com.example.fileuploaddownload.service.FileChunkService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 文件分片服务实现类
 * 使用MyBatis-Plus实现分片管理业务逻辑
 */
@Slf4j
@Service
public class FileChunkServiceImpl implements FileChunkService {

    @Autowired
    private FileChunkMapper fileChunkMapper;

    /**
     * 缓存已上传的分片信息，提高查询性能
     */
    private final Map<String, int[]> chunkCache = new ConcurrentHashMap<>();

    @Override
    public boolean saveChunk(FileChunk fileChunk) {
        try {
            // 使用MyBatis-Plus的insert或update方法
            int result;
            if (fileChunk.getId() != null) {
                result = fileChunkMapper.updateById(fileChunk);
            } else {
                // 先检查是否已存在该分片
                FileChunk existingChunk = fileChunkMapper.selectOne(
                    new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<FileChunk>()
                        .eq("identifier", fileChunk.getIdentifier())
                        .eq("chunk_index", fileChunk.getChunkIndex())
                );
                
                if (existingChunk != null) {
                    fileChunk.setId(existingChunk.getId());
                    result = fileChunkMapper.updateById(fileChunk);
                } else {
                    // 创建新的分片记录，确保即使fileId为null也能正确保存
                    // 注意：数据库中file_id字段应该允许为NULL
                    result = fileChunkMapper.insert(fileChunk);
                }
            }
            
            // 清除缓存，确保下次查询获取最新数据
            if (fileChunk.getIdentifier() != null) {
                chunkCache.remove(fileChunk.getIdentifier());
            }
            
            log.info("分片信息已保存: identifier={}, chunkIndex={}, fileId={}", 
                     fileChunk.getIdentifier(), fileChunk.getChunkIndex(), fileChunk.getFileId());
            return result > 0;
        } catch (Exception e) {
            log.error("保存分片信息失败: {}", e.getMessage(), e);
            return false;
        }
    }

    @Override
    public int[] getUploadedChunkIndexes(String identifier) {
        // 优先从缓存获取
        if (chunkCache.containsKey(identifier)) {
            return chunkCache.get(identifier);
        }
        
        try {
            // 使用Mapper方法查询已上传的分片索引
            List<Integer> chunkIndexes = fileChunkMapper.selectChunkIndexesByIdentifier(identifier);
            int[] result = chunkIndexes.stream().mapToInt(Integer::intValue).toArray();
            
            // 缓存结果
            chunkCache.put(identifier, result);
            
            log.debug("已查询到 {} 个已上传分片: identifier={}", result.length, identifier);
            return result;
        } catch (Exception e) {
            log.error("查询已上传分片失败: {}", e.getMessage(), e);
            return new int[0];
        }
    }

    @Override
    public int deleteByIdentifier(String identifier) {
        try {
            int result = fileChunkMapper.deleteByIdentifier(identifier);
            // 清除缓存
            chunkCache.remove(identifier);
            log.info("已删除 {} 个分片记录: identifier={}", result, identifier);
            return result;
        } catch (Exception e) {
            log.error("删除分片记录失败: {}", e.getMessage(), e);
            return 0;
        }
    }

    @Override
    public int deleteByFileId(Long fileId) {
        try {
            // 先查询该文件的identifier，以便清除缓存
            List<FileChunk> chunks = fileChunkMapper.selectList(
                new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<FileChunk>()
                    .eq("file_id", fileId)
            );
            
            int result = fileChunkMapper.deleteByFileId(fileId);
            
            // 清除相关缓存
            for (FileChunk chunk : chunks) {
                if (chunk.getIdentifier() != null) {
                    chunkCache.remove(chunk.getIdentifier());
                }
            }
            
            log.info("已删除 {} 个分片记录: fileId={}", result, fileId);
            return result;
        } catch (Exception e) {
            log.error("删除分片记录失败: {}", e.getMessage(), e);
            return 0;
        }
    }

    @Override
    public FileChunk getChunkByIdentifierAndIndex(String identifier, Integer chunkIndex) {
        try {
            return fileChunkMapper.selectOne(
                new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<FileChunk>()
                    .eq("identifier", identifier)
                    .eq("chunk_index", chunkIndex)
            );
        } catch (Exception e) {
            log.error("查询分片信息失败: {}", e.getMessage(), e);
            return null;
        }
    }
}